package main

import (
	"errors"
	"fmt"
	"math"
)

type emptyIntfError struct {
}

// Error is Implementation of error interface
func (e emptyIntfError) Error() string {
	return "Error: Do not allow empty Interface! "
}

type zeroError struct {
}

// Error is Implementation of error interface
func (e zeroError) Error() string {
	return fmt.Sprintf("Error: Do not allow Zero to be a divisor! ")
}

// homework1, if error return -1
func reciprocal(fs ...float64) (float64, error) {
	if len(fs) < 1 {
		return -1., emptyIntfError{}
	}

	var product float64 = 1
	for _, f := range fs {
		if f == float64(0) {
			return -1., zeroError{}
		}
		product *= f
	}

	return float64(1 / product), nil
}

// homework2, if error return -1
func reciprocalRecursion(fs ...float64) (float64, error) {
	if len(fs) == 0 {
		return -1., emptyIntfError{}
	}
	if fs[0] == float64(0) {
		return -1., errors.New("Error: Args do not allow contain zero! ")
	}
	if len(fs) == 1 {
		return 1 / fs[0], nil
	}

	r, e := reciprocalRecursion(fs[1:]...)

	return float64(r / fs[0]), e
}

// homework3
type fishTyper interface {
	swim()
}

type creeperTyper interface {
	climb()
}

type frog struct {
	name string
}

func (frog) swim() {
	fmt.Println("I am a frog, I can swim!")
}

func (frog) climb() {
	fmt.Println("I am a frog, I can climb!")
}

// homework4
func square(num interface{}) interface{} {
	switch n := num.(type) { //type-switch
	case int:
		return n * n
	case float32:
		return n * n
	case float64:
		return n * n
	case byte:
		return n * n
	case nil:
		return "Type is a nil interface! "
	default:
		return "Type is not support! "
	}
}

func main() {
	// 1. 实现一个函数，接受若干个float64（用不定长参数），返回这些参数乘积的倒数，除数为0时返回error
	r, e := reciprocal(2., 3., 4.)
	// r, e := reciprocal()
	// r, e := reciprocal(2., 0, 4.)
	if e != nil {
		fmt.Println(e)
	} else {
		fmt.Printf("Reciprocal %3.6f \n", r)
	}

	fmt.Println("")

	// 2. 上题用递归实现
	r2, e2 := reciprocalRecursion(2., 3., 4.)
	// r2, e2 := reciprocalRecursion()
	// r2, e2 := reciprocalRecursion(2., 0, 4.)
	if e2 != nil {
		fmt.Println(e2)
	} else {
		fmt.Printf("Reciprocal Recursion %3.6f \n", r2)
	}

	fmt.Println("")

	// 3. 定义两个接口：鱼类和爬行动物，再定义一个结构体：青蛙，同时实现上述两个接口

	var animal fishTyper = new(frog)
	animal.swim()

	var animal2 creeperTyper = frog{}
	animal2.climb()

	var leapfrog *frog
	leapfrog = &frog{name: "leap"}
	var animal3 fishTyper = leapfrog
	animal3.swim()

	var treefrog frog = frog{name: "leap"}
	var animal4 fishTyper = treefrog
	animal4.swim()

	fmt.Println("")

	// 4. 实现函数func square(num interface{}) interface{}，计算一个interface{}的平方，interface{}允许是4种类型：float32、float64、int、byte
	fmt.Printf("%+v\n", square(int(2)))
	fmt.Printf("%+v\n", square(float32(2.2)))
	fmt.Printf("%+v\n", square(float64(2.2)))
	fmt.Printf("%+v\n", square(byte(8)))
	var a interface{}
	fmt.Printf("%+v\n", square(a))
	fmt.Printf("math.Pow %+v\n", math.Pow(float64(2), float64(2)))

}
